package main

import (
	"fmt"
	"reflect"
)

// 结构体是一个复合类型， 用于表示一组数据， 里面可以放任何类型
// 结构体由一系列属性组成， 每个属性都有自己的类型和值
func S1() {
	//定义一个结构体
	type structA struct {
		name, hobby string
		age         int8
		allow       bool
	}

	//初始化一个结构体
	var v1 = structA{"myc", "", 28, true}

	//取值
	fmt.Println(v1.name, v1.age, v1.allow)

	//修改
	v1.name = "djr"
	fmt.Println(v1.name, v1.age, v1.allow)
}

// 重叠类型声明结构体, 指定关键字赋值
func S3() {
	type structA struct {
		name, hobby string
	}

	var v1 = structA{name: "myc", hobby: "hah"}
	fmt.Println(v1)
}

// 先声明 在赋值
func S4() {
	type structA struct {
		name  string
		age   int8
		allow bool
	}
	var v1 structA
	v1.allow = false
	v1.name = "nobody"
	v1.age = 18
	fmt.Println(v1)
}

// 结构体的嵌套
func S2() {
	type structA struct {
		name, hobby string
	}

	type structB struct {
		age   int
		other structA
	}

	// 使用匿名字段，  如果不定义名称 则名称与类型的字段相同
	type structC struct {
		hight float32
		structB
	}

	var v1 = structA{"myc", ""}
	var v2 = structB{8, v1}
	var v3 = structC{1.70, v2}
	fmt.Println(v1, reflect.TypeOf(v1), v2, reflect.TypeOf(v2), v3)
}

// 使用匿名字段嵌套结构体可以， 在赋值时可以直接使用被嵌套的结构体中的类型
func S5() {
	type structA struct {
		name string
		age  int8
	}

	type structB struct {
		hobby string
		structA
	}

	var v1 structB
	v1.name = "myc"
	v1.age = 18
	v1.hobby = "haha"
	fmt.Println(v1)

}
